package com.ssy.lingxi.dataauth.annotation.order;

import com.ssy.lingxi.dataauth.model.constant.DataAuthConstant;
import com.ssy.lingxi.dataauth.utils.DataAuthUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 供应商数据权限注解切点
 * @author 万宁
 * @version 2.0.0
 * @date 2022-01-06
 */
@Aspect
@Component
public class VendorAuthAspect {

    @Pointcut("@annotation(com.ssy.lingxi.dataauth.annotation.order.VendorAuth)")
    public void serviceAspect() {
    }

    @Before("serviceAspect()")
    public void doBefore(JoinPoint joinPoint) {
        //Step 1: 获取当前Http请求，如果HttpHeader中没有传递前端Referer、source、token、userId，不做数据权限拦截（为兼容之前的版本）
        ServletRequestAttributes servletRequestAttributes =  (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if(Objects.isNull(servletRequestAttributes)) {
            return;
        }

        HttpServletRequest request = servletRequestAttributes.getRequest();
        if(!StringUtils.hasText(request.getHeader(DataAuthConstant.HTTP_HEADER_REFERER)) || !StringUtils.hasText(request.getHeader("token")) || !StringUtils.hasText(request.getHeader("source")) || !StringUtils.hasText(request.getHeader("userId"))) {
            return;
        }

        //从HttpHeader中的Referer，找到当前请求的前端Url
        String requestPath = DataAuthUtil.findRequestPath(request.getHeader(DataAuthConstant.HTTP_HEADER_REFERER));
        if(!StringUtils.hasLength(requestPath)) {
            return;
        }

        //Step 2: 获取注解的参数值
        //获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入方法的对象
        Method method = signature.getMethod();
        //获取方法上的Aop注解
        VendorAuth annotation = method.getAnnotation(VendorAuth.class);

        //Step 3:将注解的属性值、拦截标记添加到Http的属性中，注意不是添加到Http Header中
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_TABLE_NAME_KEY, annotation.tableName());
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_MEMBER_ID_COLUMN_NAME_KEY, annotation.memberIdColumnName());
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_ROLE_ID_COLUMN_NAME_KEY, annotation.roleIdColumnName());
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_USER_ID_COLUMN_NAME_KEY, annotation.userIdColumnName());
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_DATA_AUTH_URL_KEY, requestPath);
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_AUTH_TYPE_KEY, annotation.type().getCode());

        //传入一个标记，在拦截时用于判断是否做sql拦截
        request.setAttribute(DataAuthConstant.HTTP_ATTRIBUTE_DATA_AUTH_FLAG,"1");
    }
}
